home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / jade / src / amiga_eventloop.c < prev    next >
C/C++ Source or Header  |  1995-03-09  |  7KB  |  280 lines

  1. /* amiga_eventloop.c -- Eventloop for AmigaDOS
  2.    Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>
  3.  
  4.    This file is part of Jade.
  5.  
  6.    Jade is free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    Jade is distributed in the hope that it will be useful, but
  12.    WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with Jade; see the file COPYING.    If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "jade.h"
  21. #include "jade_protos.h"
  22.  
  23. #define INTUI_V36_NAMES_ONLY
  24. #include <clib/intuition_protos.h>
  25. #include <intuition/gadgetclass.h>
  26. #include <string.h>
  27.  
  28. _PR VALUE event_loop(void);
  29.  
  30. VALUE
  31. handle_event(struct IntuiMessage *imsg)
  32. {
  33.     VW *oldvw = curr_vw, *ev_vw;
  34.     VALUE result = sym_nil;
  35.     ev_vw = (VW *)imsg->IDCMPWindow->UserData;
  36.     if(((imsg->Class != IDCMP_RAWKEY) || (!(imsg->Code & IECODE_UP_PREFIX)))
  37.        && ((imsg->Class != IDCMP_MENUPICK) || (imsg->Code != MENUNULL)))
  38.     {
  39.     switch(imsg->Class)
  40.     {
  41.         u_long code, mods;
  42.     case IDCMP_NEWSIZE:
  43.         if(ev_vw == oldvw)
  44.         cursor(ev_vw, CURS_OFF);
  45.         sys_update_dimensions(ev_vw);
  46.         ev_vw->vw_Flags |= VWFF_FORCE_REFRESH;
  47.         refresh_window(ev_vw);
  48.         if(ev_vw == oldvw)
  49.         cursor(ev_vw, CURS_ON);
  50.         break;
  51.     case IDCMP_ACTIVEWINDOW:
  52.         if(ev_vw != oldvw)
  53.         {
  54.         cursor(oldvw, CURS_OFF);
  55.         cursor(ev_vw, CURS_ON);
  56.         undo_distinct();
  57.         curr_vw = ev_vw;
  58.         }
  59.         break;
  60.     case IDCMP_MOUSEBUTTONS:
  61.     case IDCMP_MOUSEMOVE:
  62. #ifndef NOSCRLBAR
  63.         if(ev_vw->vw_SBar.gad
  64.            && (ev_vw->vw_SBar.gad->Flags & GFLG_SELECTED))
  65.         {
  66.         long newtop;
  67.         GetAttr(PGA_Top, ev_vw->vw_SBar.gad, &newtop);
  68.         if(ev_vw == oldvw)
  69.             cursor(ev_vw, CURS_OFF);
  70.         set_start_line(ev_vw, newtop);
  71.         refresh_window(ev_vw);
  72.         if(ev_vw == oldvw)
  73.             cursor(ev_vw, CURS_ON);
  74.         ev_vw->vw_SBar.top = newtop;
  75.         break;
  76.         }
  77. #endif
  78.         /* FALL THROUGH */
  79.     case IDCMP_RAWKEY:
  80.         code = mods = 0;
  81.         translate_event(&code, &mods, imsg);
  82.         if(mods & EV_TYPE_MASK)
  83.         {
  84.         curr_vw = ev_vw;
  85.         if(oldvw != ev_vw)
  86.         {
  87.             cursor(oldvw, CURS_OFF);
  88.             undo_distinct();
  89.         }
  90.         result = usekey(imsg, code, mods, (ev_vw == oldvw));
  91.         }
  92.         break;
  93.     case IDCMP_CLOSEWINDOW:
  94.         curr_vw = ev_vw;
  95.         undo_distinct();
  96.         cursor(oldvw, CURS_OFF);
  97.         result = cmd_eval_hook2(MKSTR("window-closed-hook"), sym_nil);
  98.         if(curr_vw)
  99.         {
  100.         refresh_world();
  101.         cursor(curr_vw, CURS_ON);
  102.         }
  103.         break;
  104.     case IDCMP_MENUPICK:
  105.         curr_vw = ev_vw;
  106.         reset_message(ev_vw);
  107.         if(ev_vw == oldvw)
  108.         {
  109.         cursor(curr_vw, CURS_OFF);
  110.         undo_distinct();
  111.         }
  112.         result = evalmenu(imsg->Code, imsg->Qualifier);
  113.         break;
  114. #ifndef NOSCRLBAR
  115.     case IDCMP_GADGETUP:
  116.     case IDCMP_GADGETDOWN:
  117.         if(imsg->IAddress == ev_vw->vw_SBar.gad)
  118.         {
  119.         long newtop;
  120.         GetAttr(PGA_Top, ev_vw->vw_SBar.gad, &newtop);
  121.         if(ev_vw == oldvw)
  122.             cursor(ev_vw, CURS_OFF);
  123.         set_start_line(ev_vw, newtop);
  124.         refresh_window(ev_vw);
  125.         if(ev_vw == oldvw)
  126.             cursor(ev_vw, CURS_ON);
  127.         ev_vw->vw_SBar.top = newtop;
  128.         }
  129.         break;
  130. #endif
  131.     }
  132.     }
  133.     return(result);
  134. }
  135.  
  136. VALUE
  137. event_loop(void)
  138. {
  139.     VALUE result = sym_nil;
  140.     int ticks = 0;
  141.     recurse_depth++;
  142.     std_message(curr_vw);
  143.     refresh_world_curs();
  144.     while(curr_vw)
  145.     {
  146.     u_long signals;
  147.     struct IntuiMessage *imsg;
  148.     std_message(curr_vw);
  149.     if(input_lock && rexx_sig)
  150.         signals = Wait(rexx_sig);
  151.     else
  152.         signals = Wait((1 << curr_vw->vw_Window->UserPort->mp_SigBit)
  153.                | rexx_sig | server_sig | SIGBREAKF_CTRL_C);
  154.     if(signals & SIGBREAKF_CTRL_C)
  155.         ami_interrupt_handler();
  156.     else if(rexx_sig && (signals & rexx_sig))
  157.     {
  158.         disp_rexx_port();
  159.         refresh_world_curs();
  160.     }
  161.     else if(server_sig && (signals & server_sig))
  162.         server_accept();
  163.     while(INT_P
  164.           || (curr_vw
  165.           && (imsg = (struct IntuiMessage *)
  166.               GetMsg(curr_vw->vw_Window->UserPort))))
  167.     {
  168.         if(INT_P)
  169.         result = NULL;
  170.         else
  171.         {
  172.         struct IntuiMessage imsgcopy = *imsg;
  173.         ReplyMsg((struct Message *)imsg);
  174.         if(imsg->Class == IDCMP_INTUITICKS)
  175.         {
  176.             bool refreshp = FALSE;
  177.             /* This needs fixing. Intuiticks are only received
  178.                while one of our windows is active.  */
  179.             if(++ticks >= (EVENT_TIMEOUT_LENGTH * 10))
  180.             {
  181.             ticks = 0;
  182.             if(print_event_prefix() || auto_save_buffers())
  183.                 refreshp = TRUE;
  184.             else if(data_after_gc > idle_gc_threshold)
  185.             {
  186.                 /* nothing was saved so try a GC */
  187.                 cmd_garbage_collect(sym_t);
  188.             }
  189.             else
  190.             {
  191.                 VALUE hook = cmd_symbol_value(sym_idle_hook,
  192.                               sym_t);
  193.                 if(!VOIDP(hook) && !NILP(hook))
  194.                 {
  195.                 cmd_eval_hook2(sym_idle_hook, sym_nil);
  196.                 refreshp = TRUE;
  197.                 }
  198.             }
  199.             if(refreshp)
  200.             {
  201.                 std_message(curr_vw);
  202.                 refresh_world_curs();
  203.             }
  204.             }
  205.         }
  206.         else
  207.         {
  208.             ticks = 0;
  209.             result = handle_event(&imsgcopy);
  210.         }
  211.         }
  212.         if(!result)
  213.         {
  214.         if(throw_value)
  215.         {
  216.             VALUE tv = throw_value;
  217.             VALUE car = VCAR(tv);
  218.             throw_value = NULL;
  219.             if(car == sym_exit)
  220.             {
  221.             result = VCDR(tv);
  222.             if(recurse_depth > 0)
  223.                 goto end;
  224.             }
  225.             else if((car == sym_top_level) && (recurse_depth == 0))
  226.             result = VCDR(tv);
  227.             else if(car == sym_quit)
  228.             goto end;
  229.             else if(car == sym_user_interrupt)
  230.             {
  231.             handle_error(car, sym_nil);
  232.             result = sym_nil;
  233.             }
  234.             else if(car == sym_error)
  235.             {
  236.             handle_error(VCAR(VCDR(tv)), VCDR(VCDR(tv)));
  237.             result = sym_nil;
  238.             }
  239.             else if(recurse_depth == 0)
  240.             {
  241.             result = sym_nil;
  242. #if 0
  243.             /* This is no good; we have to do the error NOW */
  244.             cmd_signal(sym_no_catcher, LIST_1(car));
  245. #else
  246.             handle_error(sym_no_catcher, LIST_1(car));
  247. #endif
  248.             }
  249.             else
  250.             {
  251.             throw_value = tv;
  252.             goto end;
  253.             }
  254.         }
  255.         else
  256.             result = sym_nil;
  257.         }
  258.     }
  259.     if(!curr_vw)
  260.         goto end;
  261. #ifndef NOSCRLBAR
  262.     if(((curr_vw->vw_Flags & VWFF_SLEEPING) == 0)
  263.        && ((curr_vw->vw_StartLine != curr_vw->vw_SBar.top)
  264.            || (curr_vw->vw_Tx->tx_NumLines != curr_vw->vw_SBar.total)))
  265.     {
  266.         sys_update_scroller(curr_vw);
  267.     }
  268. #endif
  269.     std_message(curr_vw);
  270.     if(curr_vw->vw_Flags & VWFF_REFRESH_STATUS)
  271.     {
  272.         refresh_message(curr_vw);
  273.         curr_vw->vw_Flags &= ~VWFF_REFRESH_STATUS;
  274.     }
  275.     }
  276. end:
  277.     recurse_depth--;
  278.     return(result);
  279. }
  280.